﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace WebAutomation
{
    public class TestFileReader
    {
        public List<TestCommandObject> TestCommandList = new List<TestCommandObject>();
        public static Dictionary<int, Dictionary<int, Dictionary<int, string>>> ExcelDataList = new Dictionary<int, Dictionary<int, Dictionary<int, string>>>();
        public static bool HasRemoveExcelDataBeenCalled = false;
        private string _testLines = "";
        public TestFileReader(string testLines)
        {

            _testLines = testLines;

        }


        public void ParseTestFile(ref string testName, ref string testFileName, ref string testDescription, ref string testResultsLocation, ref string browser, ref string url, ref string testRepo, ref string dbConnString, ref string failURL, ref int iterationCount, int? breakOnCount, ref string excelDataLocation,ref bool recordScreen,ref string criticalError)
        {
            List<string> listOfLines = _testLines.Split('>').ToList();
            int iCount = 0;
            foreach(var item in listOfLines)
            {
                TestCommandObject cmdObject = GetTestCommandFromLine(item, ref testName, ref testFileName, ref testDescription, ref testResultsLocation, ref browser, ref url, ref testRepo, ref dbConnString, ref failURL, ref iterationCount, ref excelDataLocation, ref recordScreen, ref criticalError);
                TestCommandList.Add(cmdObject);
                if (!string.IsNullOrEmpty(criticalError))
                {
                    break;
                }
                if (breakOnCount!=null)
                {
                    if(breakOnCount==iCount)
                    {
                        break;
                    }
                }

                iCount++;
            }

        }

        public static WebAuto.TestData GetTestData(string testline)
        {
            WebAuto.TestData returnValue = new WebAuto.TestData();
            string testName="";
            string testFileName="";
            string testDescription=""; 
            string testResultsLocation=""; 
            string browser=""; 
            string url=""; 
            string testRepo="";
            string dbConnString=""; 
            string failURL="";
            int iterationCount = 0;
            string excelDataLocation = "";
            try
            {
                if (File.Exists(testline))
                {
                    string testFile = testline;
                    String line = "";
                    using (StreamReader sr = new StreamReader(testFile))
                    {
                        while ((line = sr.ReadLine()) != null)
                        {
                            var lineArray = line.Replace("\r\n", "").Split('?');
                            if (lineArray[0].ToLower() == "browser" && lineArray[1].ToLower().Contains("data|"))
                            {
                                var testDetail = lineArray[1].Split('|')[1].Split(',');
                                browser = testDetail[0];
                                testName = testDetail[1];
                                testFileName = testDetail[2];
                                testDescription = testDetail[3];
                                url = testDetail[4];
                                testResultsLocation = testDetail[5];
                                testRepo = testDetail[6];
                                dbConnString = testDetail[7];
                                failURL = testDetail[8];
                                try
                                {
                                    iterationCount = Convert.ToInt32(testDetail[9]);
                                }
                                catch
                                {
                                    iterationCount = 1;
                                }
                                try
                                {
                                    excelDataLocation = testDetail[10];
                                }
                                catch
                                {

                                }
                                returnValue.TestDescription = testDescription;
                                returnValue.TestFileName = testFileName;
                                returnValue.TestName = testName;
                                returnValue.TestResultsFolder = testResultsLocation;
                                returnValue.TestLogFolderLocation = testResultsLocation;
                                returnValue.TestBrowser = browser;
                                break;
                            }
                        }

                        sr.Close();
                    }
                }
                else
                {
                    
                    var line = testline.Replace("\r\n", "").Split('?');
                    if (line[0].ToLower() == "browser" && line[1].ToLower().Contains("data|"))
                    {
                        var testDetail = line[1].Split('|')[1].Split(',');
                        browser = testDetail[0];
                        testName = testDetail[1];
                        testFileName = testDetail[2];
                        testDescription = testDetail[3];
                        url = testDetail[4];
                        testResultsLocation = testDetail[5];
                        testRepo = testDetail[6];
                        dbConnString = testDetail[7];
                        failURL = testDetail[8];
                        try
                        {
                            iterationCount = Convert.ToInt32(testDetail[9]);
                        }
                        catch
                        {
                            iterationCount = 1;
                        }
                        try
                        {
                            excelDataLocation = testDetail[10];
                        }
                        catch
                        {

                        }
                        returnValue.TestDescription = testDescription;
                        returnValue.TestFileName = testFileName;
                        returnValue.TestName = testName;
                        returnValue.TestResultsFolder = testResultsLocation;
                        returnValue.TestLogFolderLocation = testResultsLocation;
                        returnValue.TestBrowser = browser;
                    }
                }
            }catch
            {
            }

            return returnValue;
        }

        public static void RemoveExcelData()
        {
            try
            {
                if (ExcelDataList.Count > 0)
                {
                    int excelDataRowCount = ExcelDataList.Count;
                    int removeIndex = 0;
                    if (excelDataRowCount > 0)
                    {
                        HasRemoveExcelDataBeenCalled = true;
                        ExcelDataList.Remove(removeIndex);
                        
                    }

                }
            }catch(Exception ex)
            {
                
            }

        }

        public static string GetExcelColumnData(int columnIndex)
        {
            string returnValue = "";
            bool isFound = false;
            foreach(var item in ExcelDataList)
            {
                foreach(var item2 in item.Value)
                {
                    if (item2.Value.ContainsKey(columnIndex))
                    {
                        returnValue = item2.Value[columnIndex].ToString();
                        isFound = true;
                        break;
                    }
                }
                if(isFound)
                {
                    break;
                }


            }
            if (!isFound)
            {
                throw new Exception("The index " + columnIndex + " could not be found in the Excel Data list.");
            }

            return returnValue;
        }

        public static void CreateExcelInMemoryData(string excelDataLocation,ref int iterationCount)
        {
            try
            {

                if (!string.IsNullOrEmpty(excelDataLocation))
                {
                    if (File.Exists(excelDataLocation))
                    {
                        try
                        {
                            var excel = new LinqToExcel.ExcelQueryFactory(excelDataLocation);
                            var excelData = excel.Worksheet().ToList();
                            int excelRows = excelData.Count;
                            iterationCount = excelRows;
                            ExcelDataList = new Dictionary<int, Dictionary<int, Dictionary<int, string>>>();
                            if (excelRows > 0)
                            {

                                for (int i = 0; i <= iterationCount - 1; i++)
                                {
                                    if (!ExcelDataList.ContainsKey(i))
                                    {
                                        ExcelDataList.Add(i, new Dictionary<int, Dictionary<int, string>>());
                                    }
                                    int ii = 0;
                                    foreach (var item in excelData[i])
                                    {
                                        Dictionary<int, string> tmp = new Dictionary<int, string>();
                                        tmp.Add(ii, item.Value.ToString());
                                        ExcelDataList[i].Add(ii, tmp);
                                        ii++;

                                    }
                                }
                            }
                        }catch(Exception ex)
                        {
                            
                        }

                    }
                    else
                    {
                        iterationCount = 0;
                    }


                }
                else
                {
                    iterationCount = 0;
                }

            }catch(Exception ex)
            {
                throw new Exception("Error while parsing the excelm file." + ex.Message + "." + ex.StackTrace);

            }
        }

        public static TestCommandObject GetTestCommandFromLine(string item, ref string testName, ref string testFileName, ref string testDescription, ref string testResultsLocation, ref string browser, ref string url, ref string testRepo, ref string dbConnString, ref string failURL, ref int iterationCount, ref string excelDataLocation, ref bool recordScreen, ref string criticalError)
        {
            TestCommandObject testCommands = new TestCommandObject();
            try
            {
                item = item.Replace("\r\n", "");
                if (!item.StartsWith("//"))
                {
                    int countOfQuestionMark = item.Replace("\r\n", "").Split('?').Length - 1;
                    var line = item.Replace("\r\n", "").Split('?');
                    if (countOfQuestionMark>1)
                    {
                        line = item.Replace("\r\n", "").Split('?');
                        line[1] = line[1] + "?" + line[2];
                        line[2] = "";
                    }
                    if (item.Contains("Script"))
                    {
                        line = item.Replace("\r\n", "").Split(new string[] {"??"}, StringSplitOptions.None);
                    }
                    if (line[0].ToLower() == "browser" && line[1].ToLower().Contains("data|"))
                    {
                        var testDetail = line[1].Split('|')[1].Split(',');
                        browser = testDetail[0];
                        testName = testDetail[1];
                        testFileName = testDetail[2];
                        testDescription = testDetail[3];
                        url = testDetail[4];
                        testResultsLocation = testDetail[5];
                        testRepo = testDetail[6];
                        dbConnString = testDetail[7];
                        failURL = testDetail[8];
                        try
                        {
                            iterationCount = Convert.ToInt32(testDetail[9]);
                        }catch
                        {
                            iterationCount = 1;
                        }
                        try
                        {
                            excelDataLocation = testDetail[10];
                        }
                        catch
                        {

                        }

                        int excelIterationCount = 0;
                        if (!HasRemoveExcelDataBeenCalled)
                        {
                            CreateExcelInMemoryData(excelDataLocation, ref excelIterationCount);

                            if (excelIterationCount > 0)
                            {
                                iterationCount = excelIterationCount;
                            }
                        }
                        testCommands.CommandName = line[0];
                        if (line.Count() > 1)
                        {
                            testCommands.CommandParameters = line[1].Split('|');
                        }

                        try
                        {
                            recordScreen = Convert.ToBoolean(testDetail[11]);

                        }
                        catch
                        {
                            recordScreen = false;
                        }
                    }
                    else
                    {


                        testCommands.CommandName = line[0];
                        if (line.Count() > 1)
                        {
                            char splitChar = '|';
                            if (line[1].Contains("~"))
                            {
                                splitChar = '~';
                            }
                            testCommands.CommandParameters = line[1].Split(splitChar);
                        }
                    }
                }
            }catch(Exception ex)
            {
                //string test = item;
                criticalError="TestFileReader error." + ex.Message+"."+ex.InnerException;

            }

            return testCommands;
        }


        public int GetNoOfIterations(string line)
        {
            int noOfIterations = 1;
            string testName = "";
            string testFileName = "";
            string testDescription = "";
            string testResultsLocation = "";
            string browser = "";
            string url = "";
            string testRepo = "";
            string dbConnString = "";
            string failURL = "";
            string excelDataLocation = "";
            bool recordScreen = false;
            string criticalError = "";
            ParseTestFile(ref testName, ref testFileName, ref testDescription, ref testResultsLocation, ref browser,
                          ref url, ref testRepo, ref dbConnString, ref failURL, ref noOfIterations, 1, ref excelDataLocation, ref recordScreen, ref criticalError);

            return noOfIterations;
        }

    }
}
